/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.javahispano.javacup.tacticas_aceptadas.Arturo8a.AlianzaLima;

import java.awt.Color;
import java.util.ArrayList;
import java.util.LinkedList;
import org.javahispano.javacup.modelo.*;
import java.util.List;
import java.util.Random;

public class AlianzaLima implements Tactica {
    private Posicion[] misJugadores;



   AlianzaLimaDetalle detalle = new AlianzaLimaDetalle();

       Posicion alineacion1[]=new Posicion[]{
        new Posicion(0.4755244755244755,-52.5),
        new Posicion(-3.66 + 0.9,-52.5),
        new Posicion(0.4755244755244755,-36.58371040723982),
        new Posicion(15.692307692307693,-36.10859728506787),
        new Posicion(-14.74125874125874,-37.77149321266968),
        new Posicion(0.7132867132867133,-20.192307692307693),
        new Posicion(-27.34265734265734,-3.5633484162895925),
        new Posicion(30.909090909090907,-3.5633484162895925),
        new Posicion(-0.951048951048951,41.334841628959275),
        new Posicion(15.216783216783217,17.34162895927602),
        new Posicion(-14.97902097902098,15.203619909502263)
    };

    Posicion alineacion2[]=new Posicion[]{
        new Posicion(1.4265734265734267,-52.5),
        new Posicion(-3.5664335664335667,-52.5),
        new Posicion(-1.4265734265734267,-37.29638009049774),
        new Posicion(15.93006993006993,-35.15837104072398),
        new Posicion(-17.356643356643357,-37.77149321266968),
        new Posicion(-0.7132867132867133,-17.104072398190045),
        new Posicion(10.6993006993007,9.264705882352942),
        new Posicion(28.055944055944057,43.23529411764706),
        new Posicion(-1.4265734265734267,45.13574660633484),
        new Posicion(-15.216783216783217,7.601809954751132),
        new Posicion(-29.244755244755243,38.72171945701358)
    };

    Posicion alineacion3[]=new Posicion[]{
        new Posicion(2.377622377622378,-52.5),
        new Posicion(-3.090909090909091,-52.5),
        new Posicion(-0.7132867132867133,-37.29638009049774),
        new Posicion(16.405594405594407,-37.77149321266968),
        new Posicion(-18.78321678321678,-39.19683257918552),
        new Posicion(-1.188811188811189,-23.993212669683256),
        new Posicion(-30.909090909090907,-15.678733031674208),
        new Posicion(22.349650349650346,-12.59049773755656),
        new Posicion(-2.13986013986014,42.997737556561084),
        new Posicion(17.356643356643357,10.690045248868778),
        new Posicion(-20.685314685314687,10.690045248868778)
    };

    Posicion alineacion4[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-31.082089552238806),
        new Posicion(11.16030534351145,-31.6044776119403),
        new Posicion(28.290076335877863,-28.470149253731343),
        new Posicion(-28.290076335877863,-28.470149253731343),
        new Posicion(11.16030534351145,-1.3059701492537314),
        new Posicion(-10.641221374045802,-0.7835820895522387),
        new Posicion(-27.251908396946565,31.6044776119403),
        new Posicion(-10.641221374045802,30.559701492537314),
        new Posicion(9.603053435114505,28.992537313432837),
        new Posicion(25.69465648854962,28.992537313432837)
    };

    Posicion alineacion5[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-35.78358208955224),
        new Posicion(12.717557251908397,-35.26119402985075),
        new Posicion(28.290076335877863,-28.470149253731343),
        new Posicion(-28.290076335877863,-28.470149253731343),
        new Posicion(14.793893129770993,-18.544776119402986),
        new Posicion(-17.389312977099234,-19.58955223880597),
        new Posicion(-23.618320610687025,-0.7835820895522387),
        new Posicion(5.969465648854961,-5.485074626865671),
        new Posicion(0.2595419847328244,-0.26119402985074625),
        new Posicion(22.580152671755727,-1.3059701492537314)
    };

    Posicion alineacion6[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-35.78358208955224),
        new Posicion(12.717557251908397,-35.26119402985075),
        new Posicion(28.290076335877863,-28.470149253731343),
        new Posicion(-28.290076335877863,-28.470149253731343),
        new Posicion(14.793893129770993,-18.544776119402986),
        new Posicion(-17.389312977099234,-19.58955223880597),
        new Posicion(-23.618320610687025,-0.7835820895522387),
        new Posicion(6.4885496183206115,-6.529850746268657),
        new Posicion(-6.4885496183206115,-6.529850746268657),
        new Posicion(22.580152671755727,-1.3059701492537314)
    };




    public Posicion[] getPosicionSaca(SituacionPartido sp) {
    return alineacion1;
    }

    public Posicion[] getPosicionRecive(SituacionPartido sp) {
    return alineacion1;
    }

    public TacticaDetalle getDetalle() {
        return detalle;
    }
    
    public static boolean isGoal(double x, double y){
    	return (x>=52.5 && y>-19.5 && y<19.5) || (x<=-52.5 && y>-19.5 && y<19.5);
    }

    public double evaluarPosicionX(double pos,SituacionPartido sp){
        //System.out.println(pos);
        if(pos>34 || pos<-34) pos = sp.balon().getX();
        return pos;
    }
    public double evaluarPosicionY(double pos,SituacionPartido sp){
        if(pos>52.5 || pos<-52.5) pos = sp.balon().getY();
        return pos;
    }
    public Posicion[] getAlineacionfromBalon(SituacionPartido sp){
        Posicion alineacion[] = new Posicion[]{
        new Posicion(alineacion1[0].getX(), alineacion1[0].getY()),
        new Posicion(alineacion1[1].getX(), alineacion1[1].getY()),
        new Posicion(evaluarPosicionX(sp.balon().getX()+alineacion1[2].getX(),sp), evaluarPosicionY(sp.balon().getY()+alineacion1[2].getY(),sp)),
        new Posicion(evaluarPosicionX(sp.balon().getX()+alineacion1[3].getX(),sp), evaluarPosicionY(sp.balon().getY()+alineacion1[3].getY(),sp)),
        new Posicion(evaluarPosicionX(sp.balon().getX()+alineacion1[4].getX(),sp), evaluarPosicionY(sp.balon().getY()+alineacion1[4].getY(),sp)),
        new Posicion(evaluarPosicionX(sp.balon().getX()+alineacion1[5].getX(),sp), evaluarPosicionY(sp.balon().getY()+alineacion1[5].getY(),sp)),
        new Posicion(evaluarPosicionX(sp.balon().getX()+alineacion1[6].getX(),sp), evaluarPosicionY(sp.balon().getY()+alineacion1[6].getY(),sp)),
        new Posicion(evaluarPosicionX(sp.balon().getX()+alineacion1[7].getX(),sp), evaluarPosicionY(sp.balon().getY()+alineacion1[7].getY(),sp)),
        new Posicion(evaluarPosicionX(sp.balon().getX()+alineacion1[8].getX(),sp), evaluarPosicionY(sp.balon().getY()+alineacion1[8].getY(),sp)),
        new Posicion(evaluarPosicionX(sp.balon().getX()+alineacion1[9].getX(),sp), evaluarPosicionY(sp.balon().getY()+alineacion1[9].getY(),sp)),
        new Posicion(evaluarPosicionX(sp.balon().getX()+alineacion1[10].getX(),sp), evaluarPosicionY(sp.balon().getY()+alineacion1[10].getY(),sp))
        };
        return alineacion;
    }

    ArrayList<Comando> comandos = new ArrayList<Comando>();
    Random r = new Random();
    boolean antSaco = false;
    int itersaco = 0;

    public double getFuerzaMiJugador(int jugador,SituacionPartido sp){
        return sp.detalleMisJugadores()[jugador].getRemate();
    }

    public final double[] velocidadMisJugadores = new double[11];

    public void setVelocidadMisJugadores(SituacionPartido sp){
        for(int i=0;i<11;i++){
            velocidadMisJugadores[i] = sp.detalleMisJugadores()[i].getVelocidad();
        }
    }

    private Posicion[] misRivales = new Posicion[11];
    public final double[] velocidadMisRivales = new double[11];

    public void setVelocidadMisRivales(SituacionPartido sp){
        for(int i=0;i<11;i++){
            velocidadMisRivales[i] = sp.detalleJugadoresRivales()[i].getVelocidad();
        }
    }
    
    private Posicion[] jugadoresEnCampo = new Posicion[22];
    private double[] velocidadJugadoresEnCampo = new double[22];
    
    public void setVelocidadJugadoresEnCampo(SituacionPartido sp){
        for(int i=0;i<11;i++){
            velocidadJugadoresEnCampo[i] = velocidadMisJugadores[i];
        }
        for(int i=11;i<22;i++){
            velocidadJugadoresEnCampo[i] = velocidadMisRivales[i-11];
        }
    }

    public boolean hayRivalesMiArea(SituacionPartido sp){
        Posicion[] rivales = sp.rivales();
        for(int i=0;i<rivales.length;i++){
            if(rivales[i].getY()>=-52.5 && rivales[i].getY()<=-36 && rivales[i].getX()<=19.5 && rivales[i].getX()>=-19.5){
                return true;
            }
        }
        return false;
    }

    public boolean hayJugadoresMiArea(SituacionPartido sp){
        Posicion[] rivales = sp.misJugadores();
        for(int i=0;i<rivales.length;i++){
            if(rivales[i].getY()>=-52.5 && rivales[i].getY()<=-36 && rivales[i].getX()<=19.5 && rivales[i].getX()>=-19.5){
                return true;

            }
        }
        return false;
    }

    public boolean saqueMeta(SituacionPartido sp){
        double y = sp.balon().getY();
        double x = sp.balon().getX();
        boolean esaque = false;
        if(sp.saco() && y==-47){
            if((x==-9.16) || (x==9.16)){
                esaque = true;

            }
        }

        return esaque;
    }

    public boolean balonSaqueMeta(SituacionPartido sp){
        double y = sp.balon().getY();
        double x = sp.balon().getX();
        boolean esaque = false;
        if(y==-47){
            if((x==-9.16) || (x==9.16)){
                esaque = true;
            }
        }
        return esaque;
    }
    public boolean laTienePortero(SituacionPartido sp){
        boolean tiene = false;
        Posicion[] pos = sp.misJugadores();
        if(sp.balon().indiceMasCercano(pos)==0) tiene=true;
        return tiene;
    }

    public Posicion[] getTrayectoria(double balonDx,double balonDy,Posicion balon){
        Posicion[] trayectoria = new Posicion[11];

        for(int i=0;i<trayectoria.length;i++){
            balon = new Posicion((balon.getX()+balonDx),(balon.getY()+balonDy));
            balonDx = balonDx * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
            balonDy = balonDy * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
            trayectoria[i] =new Posicion(balon.getX(),balon.getY());
        }
        return trayectoria;
    }

    public boolean esBalonParado(double balonDx,double balonDy,Posicion balon){
        Posicion[] trayectoria = new Posicion[11];

        for(int i=0;i<trayectoria.length;i++){
            balon = new Posicion((balon.getX()+balonDx),(balon.getY()+balonDy));
            balonDx = balonDx * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
            balonDy = balonDy * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
            trayectoria[i] =new Posicion(balon.getX(),balon.getY());
        }
        return balonDx<0.2 && balonDy<0.2;
    }

    public Posicion angstrToPos(Posicion player, Posicion ball, double ang, double str, double maxStr){
    	double dist1 = -1d;
    	double dist2 = -1d;

    	double dist;
        

    	if (str == maxStr)
    		dist = 60;
    	else
    		dist = (dist1 + dist2) / 2;
    	double x = ball.getX() + Math.cos(ang)*dist;
    	double y = ball.getY() + Math.sin(ang)*dist;
    	Posicion res = new Posicion(x,y);
    	return res;
    }
    private int sumAround(int[] goodPass, int n, int numAngles) {
		int res = 0;
    	for (int i = n - numAngles; i <= n + numAngles; ++i){
			int k = i % goodPass.length;
			if (k < 0)
				k+= goodPass.length;
			res += goodPass[k];
		}
		return res;
	}

    private boolean estaDentroCampo(Posicion p) {
        return (p.getX() > -34 && p.getX() < 34 &&
                p.getY() > -52.5 && p.getY() < 52.5);
    }
    public double redondeaMultiplo(double valor, double divisor) {
        return Math.round(valor / divisor) * divisor;
    }
    SituacionPartido sp;
    public Posicion getPosicionFinal(double balonDx,double balonDy,double balonDz){
        boolean suelo = false;
        Posicion balon = sp.balon();
        double alturaBalon = sp.alturaBalon();
        boolean rebote=false;
        for(int i=0;i<100 && balonDx!=0;i++){
        if (!suelo && (alturaBalon==0) && (balonDz>=0) && balonDz<Constantes.G * 3) {
            suelo = true;
        }
        if (suelo) {
            balon = balon.moverPosicion(balonDx, balonDy);
            balonDx = balonDx * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
            balonDy = balonDy * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
        } else {
            alturaBalon = redondeaMultiplo(alturaBalon + balonDz, Constantes.G);
            balon = balon.moverPosicion(balonDx, balonDy);
            balonDz = redondeaMultiplo(balonDz - Constantes.G, Constantes.G);
            balonDx = balonDx * Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE;
            balonDy = balonDy * Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE;
            if (alturaBalon == 0) {
                balonDz = (-balonDz - Constantes.G) * Constantes.FACTOR_DISMINUCION_ALTURA_BALON_REBOTE;
                balonDz = redondeaMultiplo(balonDz, Constantes.G);
                rebote = true;
            }
        }
        if(balonDx==0d && balonDy==0d && balonDz==0d) break;
        }
        return balon;
    }
    public Posicion setDentroCampoJuego(Posicion p) {
        double mx = Constantes.ANCHO_CAMPO_JUEGO / 2;
        double my = Constantes.LARGO_CAMPO_JUEGO / 2;
        double x0 = p.getX(), y0 = p.getY();
        if (x0 > mx) {
            x0 = mx;
        }

        if (x0 < -mx) {
            x0 = -mx;
        }

        if (y0 > my) {
            y0 = my;
        }

        if (y0 < -my) {
            y0 = -my;
        }
        return new Posicion(x0, y0);
    }
    public void regateLargo(ArrayList<Comando> comandos,int n, SituacionPartido sp){
        double miVelocidad = Constantes.getVelocidad(sp.detalleMisJugadores()[n].getRemate())+.2;
        double distMin = miVelocidad*12;
        double incrementoAngulo = 1.005*Math.PI/10/10;
        double velocidadRemateMaximo = Constantes.getVelocidadRemate(getFuerzaMiJugador(n, sp));
        double miFuerza = getFuerzaMiJugador(n, sp);
        int laFuerza = (int)velocidadRemateMaximo;
        int posiblesShoots = 0;
        boolean posible=true;
        Posicion[] posiblesTiros = new Posicion[21*20*10];
        //System.out.println((int)miFuerza*20*10);
        for(int i=0;i<posiblesTiros.length;i++){
            posiblesTiros[i]= new Posicion(0,52.5);
        }
        int j=0;
        DoubleFor : for (double str = 0; str <=1; str+=0.1){
            //System.out.println(str);
            double numRivalesMasCercanos = 0;
    		for (double angulo = 0; angulo < 2*Math.PI; angulo+=incrementoAngulo){
                double velocidadRematePrueba = str*Constantes.getVelocidadRemate(getFuerzaMiJugador(n, sp));
                double balonDx = Math.cos(angulo) * velocidadRematePrueba;
                double balonDy = Math.sin(angulo) * velocidadRematePrueba;
                double balonDz = 0;
                Posicion puntoFinal = getPosicionFinal(balonDx, balonDy, balonDz);
               for(int i=0;i<misRivales.length;i++){
                       double velocidadRival = getVelocidadMisRivales(i);
                       double recorridoRival = velocidadRival*12;
                       if((misRivales[i].distancia(puntoFinal))<recorridoRival)
                           posible = false;
                }
                if(posible!=false){
                    posiblesTiros[j] = puntoFinal;
                }
                else{
                    posible=true;
                }
                if(j++ > posiblesTiros.length)
                    break DoubleFor;
            }
        }
        double menorDistancia = 1000;
        int indice=0;
        int cuantos = posiblesTiros.length;
        for(int i=0;i<posiblesTiros.length;i++){
            if(posiblesTiros[i].distancia(Constantes.centroArcoSup)<menorDistancia && estaDentroCampo(posiblesTiros[i])){
                menorDistancia = menorDistancia(posiblesTiros[i].distancia(Constantes.centroArcoSup), posiblesTiros[i].distancia(Constantes.posteDerArcoSup), posiblesTiros[i].distancia(Constantes.posteIzqArcoSup));
                indice = i;
            }
        }
        if(j==0 || j==1){
            comandos.add(new ComandoGolpearBalon(n, misJugadores[8], 1, true));
        }
        if(sp.iteracionesParaRematar()[n]==0){
        comandos.add(new ComandoGolpearBalon(n));
        comandos.add(new ComandoIrA(n, posiblesTiros[indice]));
        }

    }
    public double getVelocidadMisJugadores(int n){
        return sp.detalleMisJugadores()[n].getVelocidad();
    }
    public double getVelocidadMisRivales(int n){
        return sp.detalleJugadoresRivales()[n].getVelocidad();
    }

    public void regateCorto(ArrayList<Comando> comandos,int n){
        double miVelocidad = getVelocidadMisJugadores(n)+.2;
        double incrementoAngulo = 1.005*Math.PI/10/10;
        Posicion balon = sp.balon();
        boolean posible=true;
        Posicion[] posiblesTiros = new Posicion[360];
        for(int i=0;i<posiblesTiros.length;i++){
            posiblesTiros[i]= new Posicion(-100,-100);
        }
        int j=0;
        for (double angulo = 0; angulo < 2*Math.PI; angulo+=incrementoAngulo){
                Posicion puntoFinal = new Posicion(balon.getX()+Math.cos(angulo)*miVelocidad,balon.getY()+Math.sin(angulo)*miVelocidad);
                   for(int i=0;i<misRivales.length;i++){
                       double velocidadRival = getVelocidadMisRivales(i);

                       if((misRivales[i].distancia(puntoFinal))<=1)
                           posible = false;
                   }
                if(posible!=false)
                    posiblesTiros[j] = puntoFinal;
                else
                    posible=true;
                j++;
            }
        double menorDistancia = 1000;
        int indice=0;
        for(int i=0;i<posiblesTiros.length;i++){
            if(menorDistancia(posiblesTiros[i].distancia(Constantes.centroArcoSup), posiblesTiros[i].distancia(Constantes.posteDerArcoSup), posiblesTiros[i].distancia(Constantes.posteIzqArcoSup))<menorDistancia && estaDentroCampo(posiblesTiros[i])){
                menorDistancia = menorDistancia(posiblesTiros[i].distancia(Constantes.centroArcoSup), posiblesTiros[i].distancia(Constantes.posteDerArcoSup), posiblesTiros[i].distancia(Constantes.posteIzqArcoSup));
                indice = i;
            }
        }
       
        comandos.add(new ComandoGolpearBalon(n));
        comandos.add(new ComandoIrA(n, posiblesTiros[indice]));
    }
    	
    
    Balon balon = new Balon();
    boolean primerLlamado = true;
    Posicion b;
    int masCercano;

    public Posicion getPosicionInicial(int n){
        return alineacion1[n];
    }
    public static double control(double numero, double min, double max){
        if (numero<min) return min;
        if (numero>max) return max;
        return numero;
    }

    public Posicion[] getTrayectoriaDisparo(int jugador,Posicion balon,Posicion destino, double porcionFuerza){
        Posicion[] trayectoria = new Posicion[100];
		double x = balon.getX();
		double y = balon.getY();
		trayectoria[0] = new Posicion(x,y);
        double vel = porcionFuerza*Constantes.getVelocidadRemate(getFuerzaMiJugador(jugador, sp));
        double balonDx = Math.cos(balon.angulo(destino)) * vel;
        double balonDy = Math.sin(balon.angulo(destino)) * vel;

        for(int i=1;i<trayectoria.length;i++){
            balon = new Posicion((balon.getX()+balonDx),(balon.getY()+balonDy));
            balonDx = balonDx * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
            balonDy = balonDy * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
            trayectoria[i] =new Posicion(balon.getX(),balon.getY());
        }
		return trayectoria;
    }

    public double menorDistancia (double a, double b, double c){
        if(a<b && a<c) return a;
        if(b<a && b<c) return b;
        if(c<a && c<b) return c;
        return a;
    }

    public double queFuerzaUsar(int n,Posicion destino){
        double fuerzaAUsar = 1;
        for (double str=0; str<=1; str+=0.1){
            Posicion[] recorridoBalon = getTrayectoriaDisparo(n, sp.balon(), destino, str);
            if(recorridoBalon[recorridoBalon.length-1].distancia(destino)<3){
                fuerzaAUsar = str;
                break;
            }
        }
        //System.out.println("fuerza "+fuerzaAUsar);
        return fuerzaAUsar;
    }
    public Posicion getPaloMasLejosArquero(Posicion pateador){
        int indice = 0;
        for(int i=0;i<misRivales.length;i++){
            if(sp.detalleJugadoresRivales()[i].esPortero()){
                indice = i;
                break;
            }
        }
        Posicion puntoMasCercano = new Posicion(52.5,0);
        if(pateador.distancia(Constantes.posteDerArcoSup)<pateador.distancia(Constantes.posteIzqArcoSup))
            puntoMasCercano = Constantes.posteDerArcoSup;
        else
            puntoMasCercano = Constantes.posteIzqArcoSup;
        Posicion portero = misRivales[indice];
        double x=0;
        if(portero.getX()>0)
            x = control(portero.getX()+1.6, 0, Constantes.posteIzqArcoSup.getX());
        if(portero.getX()==0)
            x = control(portero.getX()+1.6, 0, puntoMasCercano.getX());
        if(portero.getX()<0)
            x = control(portero.getX()+1.6, 0, Constantes.posteDerArcoSup.getX());


        return new Posicion(x,52.5);

    }

    public boolean getDelanteroLibre(){
        for(int i=0;i<misRivales.length;i++){
            if(misJugadores[8].distancia(misRivales[i])>1)
                return true;
        }
        return false;
    }

    public int getJugadorCercanoFueraArea(){
        double minDist = 1000;
        int indice = 6;
        for(int i=2;i<misJugadores.length;i++){
            if(misJugadores[i].distancia(sp.balon())<minDist && misJugadores[i].getY()>-34){
                minDist = misJugadores[i].distancia(sp.balon());
                indice = i;
            }
        }
        return indice;
    }
    Random rand = new Random();
    final Posicion CENTROPORTERIA = new Posicion(0, -52);
    public void colocar(List comandos, double radio)
    {
        double incr = (165 - 15) / 9;
        double angulo = 15;
        angulo = angulo + Math.random() * incr - incr/2;

        for (int i = 1; i < 11; i++) {
            Posicion posJug = CENTROPORTERIA.moverAngulo(Math.toRadians(angulo), radio, 25);
            comandos.add(new ComandoIrA(i, posJug));

            angulo += incr;
        }

    }
    public List<Comando> ejecutar(SituacionPartido sp) {
        this.sp=sp;
        balon.setSP(sp);
        balon.actualizarBalon();
        if(primerLlamado){
            setVelocidadMisJugadores(sp);
            setVelocidadMisRivales(sp);
            setVelocidadJugadoresEnCampo(sp);
            primerLlamado = false;
        }
        b = sp.balon();
        masCercano = balon.getMasCercanoDeBola();
        misJugadores = sp.misJugadores();
        misRivales = sp.rivales();
        double decision = Math.random();
        if((sp.golesRival()-sp.golesPropios())<2){
        if(misJugadores[balon.getMasCercanoDeBola()].distancia(sp.balon())<=1)
        {
            int jugador = balon.getMasCercanoDeBola();
                regateLargo(comandos, balon.getMasCercanoDeBola(), sp);
            }

            
        
        for (int i : sp.puedenRematar()) {

        }
        Posicion[] trayectoria = balon.getTrayectoria();


        Posicion alineacionDinamica[] = new Posicion[11];
        alineacionDinamica = getAlineacionfromBalon(sp);
        comandos.clear();
        for (int i = 0; i < 11; i++) {
            comandos.add(new ComandoIrA(i, alineacionDinamica[i]));
        }
        for(int i=2;i<6;i++){
            if(misJugadores[i].distancia(alineacion2[i])>55)
                comandos.add(new ComandoIrA(i, alineacion2[i]));
        }
        for(int i=6;i<11;i++){
            if(i!=8){
            if(misJugadores[i].distancia(alineacion2[i])>80)
                comandos.add(new ComandoIrA(i, alineacion2[i]));
            }
        }

        int masCercano = sp.balon().indiceMasCercano(misJugadores);
        comandos.add(new ComandoIrA(masCercano,sp.balon()));
        if(misJugadores[masCercano].distancia(sp.balon())<=1){
            regateLargo(comandos, masCercano, sp);
            if (misJugadores[masCercano].distancia(Constantes.centroArcoSup) < 20) { // si estoy a 20 metros del arco
                if(decision>0.5)
                    comandos.add(new ComandoGolpearBalon(masCercano, getPaloMasLejosArquero(misJugadores[0]), 1, false)); // pateo
                else
                    comandos.add(new ComandoGolpearBalon(masCercano, getPaloMasLejosArquero(misJugadores[0]), 1, true));

                }
        }


        if(decision>0.5){
            for (int i : sp.puedenRematar()) {
                boolean adelante = false;
                for (int j : misJugadores[i].indicesMasCercanos(misJugadores, i)) {
                    if (misJugadores[j].getY() > misJugadores[i].getY()) {
                        if (i == 8) {
                            comandos.add(new ComandoGolpearBalon(i, misJugadores[j], .85, 22));
                        } else {
                            comandos.add(new ComandoGolpearBalon(i, misJugadores[j], 1, 22));
                        }
                        adelante = true;
                        break;
                    }
                }
                if (!adelante) {
                    comandos.add(new ComandoIrA(i, Constantes.centroArcoSup));
                    comandos.add(new ComandoGolpearBalon(i));
                }
                if (misJugadores[i].distancia(Constantes.centroArcoSup) < 40) {

                    comandos.add(new ComandoGolpearBalon(i, Constantes.posteDerArcoSup, 1, 20));

                }
            }
        }

            
            /* acciones del 9*/
            Posicion delantero9 = new Posicion(-0.951048951048951,41.334841628959275);
            if(misJugadores[8].distancia(delantero9)>8)
                comandos.add(new ComandoIrA(8, delantero9));
            if(misJugadores[8].distancia(sp.balon())<8)
                comandos.add(new ComandoIrA(8,sp.balon()));
            if(misJugadores[8].distancia(sp.balon())<1){
                comandos.add(new ComandoGolpearBalon(8, getPaloMasLejosArquero(delantero9), 1, false));
            }

            /* definir acciones
             * del portero */
            if(balon.getMasCercanoDeBola()==0){
                if(misJugadores[0].distancia(sp.balon())<1.5){
                    comandos.add(new ComandoGolpearBalon(0, Constantes.centroArcoSup, 1, 30));
                }
            }
            Posicion posicionArquero = Posicion.Interseccion(sp.balon(), balon.getPosicionFinal(), Constantes.posteIzqArcoInf, Constantes.posteDerArcoInf);
            if(posicionArquero!=null){
                posicionArquero = new Posicion(control(posicionArquero.getX(),-(Constantes.LARGO_ARCO / 2)+2.49,(Constantes.LARGO_ARCO / 2)-1.49),-52.5);
                comandos.add(new ComandoIrA(0, posicionArquero));
            }else{
                comandos.add(new ComandoIrA(0, Constantes.centroArcoInf));
            }

            if(balonSaqueMeta(sp))
                comandos.add(new ComandoIrA(0, balon.getPosicionActual()));
            double menor = 100;
            int indice = 1;
            for(int i=2;i<11;i++){
                double dist = misJugadores[i].distancia(Constantes.centroArcoInf);
                if(dist<menor){
                    menor = dist;
                    indice = i;
                }
            }
            if(misJugadores[indice].getY()>sp.balon().getY() && sp.balon().distancia(Constantes.centroArcoInf)<menor && sp.alturaBalon()==0)
                comandos.add(new ComandoIrA(0, sp.balon()));

            /* definir acciones
             * del portero 2 */
            if(balon.getMasCercanoDeBola()==1){
                if(misJugadores[1].distancia(sp.balon())<1){
                    comandos.add(new ComandoGolpearBalon(1, Constantes.centroArcoSup, 1, 30));
                }
            }
            posicionArquero = Posicion.Interseccion(sp.balon(), balon.getPosicionFinal(), Constantes.posteIzqArcoInf, Constantes.posteDerArcoInf);
            if(posicionArquero!=null){
                posicionArquero = new Posicion(control(posicionArquero.getX(),-(Constantes.LARGO_ARCO / 2)+1.49,(Constantes.LARGO_ARCO / 2)-1.49),-52.5);
                comandos.add(new ComandoIrA(0, posicionArquero));
            }else{
                comandos.add(new ComandoIrA(0, Constantes.centroArcoInf));
            }

            if (!balon.estoyMasCercaDeBola()){
	    		ArrayList<Integer> playersAvailable = new ArrayList<Integer>();
	    		for (int z = 1; z < 6; ++z)
	    			playersAvailable.add(new Integer(z));
	    		for (int z = 0; z < misRivales.length; ++z){
	    			if (misRivales[z].getY() <= 0){
	    				double distMin = 1000;
	    				int playerMin = 0;
	    				for (int k = 0; k < playersAvailable.size(); ++k){
	    					double dist = misRivales[z].distancia(misRivales[playersAvailable.get(k)]);
	    					if (dist < distMin){
	    						distMin = dist;
	    						playerMin = playersAvailable.get(k);
	    					}
	    				}
                        comandos.add(new ComandoIrA(playerMin, misRivales[z]));
	    			}
	    		}
    		}

            for(int i=2;i<6;i++)
                comandos.add(new ComandoGolpearBalon(i,new Posicion(Math.random()*50-25,0), 1.0, 30.0));
        

    }else{
        List cc = new ArrayList();

        colocar(cc, 2.5);

        double porx = Math.max(-3, sp.balon().getX());
        porx = Math.min(3, porx);

        cc.add(new ComandoIrA(0, new Posicion(porx,-52.5)));

        for (int i = 1; i < 11; i++) cc.add(new ComandoGolpearBalon(i,new Posicion(Math.random()*50-25,0), 1.0, 30.0));
if(balon.getMasCercanoDeBola()==0){
                if(misJugadores[0].distancia(sp.balon())<1.5){
                    comandos.add(new ComandoGolpearBalon(0, Constantes.centroArcoSup, 1, 30));
                }
            }
            Posicion posicionArquero = Posicion.Interseccion(sp.balon(), balon.getPosicionFinal(), Constantes.posteIzqArcoInf, Constantes.posteDerArcoInf);
            if(posicionArquero!=null){
                posicionArquero = new Posicion(control(posicionArquero.getX(),-(Constantes.LARGO_ARCO / 2)+1.49,(Constantes.LARGO_ARCO / 2)-1.49),-52.5);
                comandos.add(new ComandoIrA(0, posicionArquero));
            }else{
                comandos.add(new ComandoIrA(0, Constantes.centroArcoInf));
            }
            comandos.add(new ComandoIrA(0, balon.getPosicionFinal()));

            if(balonSaqueMeta(sp))
                comandos.add(new ComandoIrA(0, sp.balon()));
            double menor = 100;
            int indice = 1;
            for(int i=2;i<11;i++){
                double dist = misJugadores[i].distancia(Constantes.centroArcoInf);
                if(dist<menor){
                    menor = dist;
                    indice = i;
                }
            }
            if(misJugadores[indice].getY()>sp.balon().getY() && sp.balon().distancia(Constantes.centroArcoInf)<menor && sp.alturaBalon()==0)
                comandos.add(new ComandoIrA(0, sp.balon()));
            return cc;
    }




    return comandos;
}
}